package DistSys;

import java.util.*;
import java.awt.*;

import DistSys.SysConst;
import Element.*;

public class ProjectInfo {

    public static final int BG_IMAGE_LAYER= -2;
    public static final int BG_LINE_LAYER = -1;
    public static final int NUM_BACK_GND_LAYER = 2;
    public static final int NUM_FORE_GND_LAYER = 10; //{ 0, 1,...,9 }
    public static final int NUM_LAYER = NUM_BACK_GND_LAYER + NUM_FORE_GND_LAYER;

    // CONSTANTS to identify the mode of shading
    public static final int SHADE_NONE             =  -1;
    public static final int SHADE_BY_ZONE          =  -2;
    public static final int SHADE_BY_STUDY_AREA    =  -3;
    public static final int SHADE_BY_NOM_VOLTAGE   =  -4;
    // to add further shading CONSTANTS change the SHADE_BY_NOM_VOLTAGE constant
    // in "DrawingPanel.java" to the new one with the lowest number

    public static String sVersion = "1.0";

    public Vector layerList;
    public int    iActiveLayer;

    public Vector storedShadingOptions;
    public transient ShadingOption currentShadingOption;
    public int shadingCat;

    public Vector activeTempList; //for I/O usage
    public Vector allZone;

    public boolean showLegend;
    public boolean showScale;
    public boolean showGridLine;
    public boolean showNodes;
    public boolean drawText;
    public boolean freeze;

    public boolean isHighLightOpenPoints;
    public boolean isHighLightProtection;
    public boolean isHighLightSect;
    public boolean isHighLightSelected;

    public double dZoomFactor;
    public double dPrevZoomFactor;

    public double lengthPerUnit;
    public int    unitOfLength;
    public double gridWidth; //in virtual resolution

    public ProjectInfo(){
        //create objects
        storedShadingOptions = new Vector();
        currentShadingOption = new ShadingOption();
        allZone = new Vector(50,50);
        activeTempList=new Vector(50,50);
        layerList = new Vector(NUM_LAYER);

        //set initial values
        init();
    }

    /**
     * This is also called by Sys.reset(), which is called at "New Project"
     */
    public void init(){   //set init values
        initLayerList();
        //default active layer =0
        iActiveLayer = 0 ;

        // default shading is normal
        shadingCat = SHADE_NONE;
        //Remove shadings; will be load from DBAccessor.initProject()
        storedShadingOptions.removeAllElements();

        allZone.removeAllElements();
        allZone.add( new Zone() );  //zone=0 & color=gray

        showLegend = true;
        showScale = false;
        showGridLine = false;
        showNodes = true;
        drawText = true;
        freeze = false;

        isHighLightOpenPoints =false;
        isHighLightProtection =false;
        isHighLightSect =false;
        isHighLightSelected =false;

        dZoomFactor= 8.0F; //by default
        dPrevZoomFactor=8.0F;

        //(SysConst.SCALEBAR_LENGTH/Sys.dZoomFactor)=virtual resolution
        lengthPerUnit=0.1/(SysConst.SCALEBAR_LENGTH/dZoomFactor);
        unitOfLength = SysConst.UNIT_MILE; //in miles
        gridWidth=(SysConst.SCALEBAR_LENGTH/dZoomFactor); //in virtual resolution
    }

    public void initLayerList(){
        layerList.removeAllElements();
        Layer layer;
        int   index;
        for(int i=0; i< NUM_LAYER; i++){
            index = i - NUM_BACK_GND_LAYER;
            layer = new Layer(index,"Layer "+index, 0, 0 );
            if      (index==BG_IMAGE_LAYER) { layer.setName("Images"); }
            else if (index==BG_LINE_LAYER ) { layer.setName("Background"); }
            layerList.add(i, layer);
        }
    }


  public void incZoomFactor() {
      dPrevZoomFactor = dZoomFactor;
      dZoomFactor *=1.25F;
  }

  public void decZoomFactor() {
      dPrevZoomFactor = dZoomFactor;
      dZoomFactor *=0.8F;
  }

  public void setZoomFactor( double s){
      dPrevZoomFactor = dZoomFactor;
      dZoomFactor = s;
  }

  public void toggleZoomFactor() {
      double tmp=dZoomFactor;
      dZoomFactor =dPrevZoomFactor;
      dPrevZoomFactor = tmp;
  }

  public String getUnitInString(){
      return SysConst.unitStrings[unitOfLength];
  }



  public int checkActiveTemp(AbsElem del) {
      AbsElem n = (AbsElem)Templates.subLists[del.getType()].elementAt(0);
      int c = 0;
      if (del.equals(Line.objActiveTemp))     { Line.objActiveTemp     = n;c++;}
      if (del.equals(Line.objActiveTemp2))    { Line.objActiveTemp2    = n;c++;}
      if (del.equals(Load.objActiveTemp))     { Load.objActiveTemp     = n;c++;}
      if (del.equals(Txfm.objActiveTemp))     { Txfm.objActiveTemp     = n;c++;}
      if (del.equals(Regulator.objActiveTemp)){ Regulator.objActiveTemp= n;c++;}
      if (del.equals(Breaker.objActiveTemp))  { Breaker.objActiveTemp  = n;c++;}
      if (del.equals(DrtBreaker.objActiveTemp)){DrtBreaker.objActiveTemp=n;c++;}
      if (del.equals(Fuse.objActiveTemp))     { Fuse.objActiveTemp     = n;c++;}
      if (del.equals(Switch.objActiveTemp))   { Switch.objActiveTemp   = n;c++;}
      if (del.equals(Switch3.objActiveTemp))  { Switch3.objActiveTemp  = n;c++;}
      if (del.equals(SwitchGnd.objActiveTemp)){ SwitchGnd.objActiveTemp= n;c++;}
      if (del.equals(Recloser.objActiveTemp)) { Recloser.objActiveTemp = n;c++;}
      if (del.equals(Sect.objActiveTemp))     { Sect.objActiveTemp     = n;c++;}
      if (del.equals(Cap.objActiveTemp))      { Cap.objActiveTemp      = n;c++;}
      if (del.equals(Reactor.objActiveTemp))  { Reactor.objActiveTemp  = n;c++;}
      if (del.equals(SeriesCap.objActiveTemp)){ SeriesCap.objActiveTemp= n;c++;}
      if (del.equals(Motor.objActiveTemp))    { Motor.objActiveTemp    = n;c++;}
      if (del.equals(Arrester.objActiveTemp)) { Arrester.objActiveTemp = n;c++;}
      if (del.equals(CT.objActiveTemp))       { CT.objActiveTemp       = n;c++;}
      if (del.equals(PT.objActiveTemp))       { PT.objActiveTemp       = n;c++;}
      if (del.equals(Bus.objActiveTemp))      { Bus.objActiveTemp      = n;c++;}
      if (del.equals(DG.objActiveTemp))       { DG.objActiveTemp       = n;c++;}
      if (del.equals(Source.objActiveTemp))   { Source.objActiveTemp   = n;c++;}
      if (del.equals(Group.objActiveTemp))    { Group.objActiveTemp    = n;c++;}
      return c;
  }


  //add a new zone only if not existed in current zone list
  public void addZoneIfUnexisted( Zone znObj){
      int sz = allZone.size();
      Zone znExisted;
      for(int i=0; i<sz; i++){
          znExisted = (Zone) allZone.get(i);
          if( znObj.getZoneNumber() == znExisted.getZoneNumber() ){
              return; //no Zone added
          }
      }
      //not existed. It is a new zone
      allZone.add( znObj);
  }

  public void addZoneIfUnexisted(double dZone, Color clr){
      addZoneIfUnexisted( new Zone(dZone, clr) );
  }

  public boolean hasAnyHighLight(){
      return (  this.isHighLightOpenPoints || this.isHighLightProtection
                || this.isHighLightSect || this.isHighLightSelected );
  }

}


/*  public void collectActiveTemp(){
      activeTempList.add(0, Line.objActiveTemp);
      activeTempList.add(1, Line.objActiveTemp2);
      activeTempList.add(2, Load.objActiveTemp);
      activeTempList.add(3, Txfm.objActiveTemp);
      activeTempList.add(4, Regulator.objActiveTemp);
      activeTempList.add(5, Breaker.objActiveTemp);
      activeTempList.add(6, DrtBreaker.objActiveTemp);
      activeTempList.add(7, Fuse.objActiveTemp);
      activeTempList.add(8, Switch.objActiveTemp);
      activeTempList.add(9, Switch3.objActiveTemp);
      activeTempList.add(10, SwitchGnd.objActiveTemp);
      activeTempList.add(11, Recloser.objActiveTemp);
      activeTempList.add(12, Sect.objActiveTemp);
      activeTempList.add(13, Cap.objActiveTemp);
      activeTempList.add(14, Reactor.objActiveTemp);
      activeTempList.add(15, SeriesCap.objActiveTemp);
      activeTempList.add(16, Motor.objActiveTemp);
      activeTempList.add(17, Arrester.objActiveTemp);
      activeTempList.add(18, CT.objActiveTemp);
      activeTempList.add(19, PT.objActiveTemp);
      activeTempList.add(20, Bus.objActiveTemp);
      activeTempList.add(21, DG.objActiveTemp);
      activeTempList.add(22, Source.objActiveTemp);
      activeTempList.add(23, Group.objActiveTemp);
  }

  public void assignActiveTemp(){
      if( activeTempList==null ) return; //very early version
      else if( activeTempList.size()<24) return; //preventative protection

      Line.objActiveTemp       = (AbsElem)activeTempList.elementAt(0);
      Line.objActiveTemp2      = (AbsElem)activeTempList.elementAt(1);
      Load.objActiveTemp       = (AbsElem)activeTempList.elementAt(2);
      Txfm.objActiveTemp       = (AbsElem)activeTempList.elementAt(3);
      Regulator.objActiveTemp  = (AbsElem)activeTempList.elementAt(4);
      Breaker.objActiveTemp    = (AbsElem)activeTempList.elementAt(5);
      DrtBreaker.objActiveTemp = (AbsElem)activeTempList.elementAt(6);
      Fuse.objActiveTemp       = (AbsElem)activeTempList.elementAt(7);
      Switch.objActiveTemp     = (AbsElem)activeTempList.elementAt(8);
      Switch3.objActiveTemp    = (AbsElem)activeTempList.elementAt(9);
      SwitchGnd.objActiveTemp  = (AbsElem)activeTempList.elementAt(10);
      Recloser.objActiveTemp   = (AbsElem)activeTempList.elementAt(11);
      Sect.objActiveTemp       = (AbsElem)activeTempList.elementAt(12);
      Cap.objActiveTemp        = (AbsElem)activeTempList.elementAt(13);
      Reactor.objActiveTemp    = (AbsElem)activeTempList.elementAt(14);
      SeriesCap.objActiveTemp  = (AbsElem)activeTempList.elementAt(15);
      Motor.objActiveTemp      = (AbsElem)activeTempList.elementAt(16);
      Arrester.objActiveTemp   = (AbsElem)activeTempList.elementAt(17);
      CT.objActiveTemp         = (AbsElem)activeTempList.elementAt(18);
      PT.objActiveTemp         = (AbsElem)activeTempList.elementAt(19);
      Bus.objActiveTemp        = (AbsElem)activeTempList.elementAt(20);
      DG.objActiveTemp         = (AbsElem)activeTempList.elementAt(21);
      Source.objActiveTemp     = (AbsElem)activeTempList.elementAt(22);
      Group.objActiveTemp      = (AbsElem)activeTempList.elementAt(23);
  }
*/